
const { Base_ClientsManager, Base_ClientManager} = require('../../ws_frame/server/class/Base_ClientsManager.js');
const Response = require('./Response.js');
    

class ClientsManager extends Base_ClientsManager {
    
    constructor(){
        super();
        this.onlinePlayers = {}; //同步服务器在线的玩家 {"BDSUuid": {"231232312": {xuid:231232312, uuid: fksjiojrew, realName: fasdfaef, loginTime: 2313}}}
    }

    /**
     * @description: 广播json消息
     * @param {object} json
     * @param {Array} exceptId 排除的客户端id
     */
    broadcastJson(json, exceptId=[]){
        this.forEach(client => {
            client.sendJson(json);
        }, exceptId);
    }

    /**
     * @description: 广播文本消息
     * @param {string} msg
     * @param {Array} exceptId 排除的客户端id
     */
    broadcastText(msg, exceptId=[]){
        this.forEach(client => {
            client.sendText(msg);
        }, exceptId);
    }

    /**
     * @description: 广播命令
     * @param {string} cmd
     * @param {Array} exceptId 排除的客户端id
     */
    broadcastCmd(cmd, exceptId=[]){
        this.forEach(client => {
            client.runcmd(cmd);
        }, exceptId);
    }


    /**
     * @description: 广播控制台日志消息
     * @param {*} msg
     * @param {*} level 日志等级
     * @param {*} exceptId
     * @return {*}
     */    
    broadcastLogger(msg, level='info', exceptId=[]){
        this.forEach(client => {
            client.sendLogger(msg, level);
        }, exceptId);
    }

    /**
     * @description: 获取在线的客户端信息
     * @return {*} 
     */ 
    getOnlineClientsInfo(){
        let clientInfo = {};
        this.forEach(client=>{
            clientInfo[client.id] = client.getClientInfo();
            clientInfo[client.id]['onlinePlayers'] = this.onlinePlayers[client?.bds?.uuid]??{};
        });
        return clientInfo;
    }

    /**
     * @description: 获取在线的客户端列表
     * @return {string} flysteve(1), ziyuan(2)
     */    
    getOnlineClientsName(){
        let onlines = [];
        this.forEach((client) =>(onlines.push(`${client.name}(${client.id})`)));
        if (onlines.length == 0){
            return '无客户端连接';
        }
        return onlines.join(", ");
    }

    /**
     * @description: 获取在线的玩家列表
     * @return {*}
     */    
    getOnlinePlayersName(){
        let plCount = 0;
        let listRes = '';
        for (let bdsuuid in this.onlinePlayers){
            if (Object.values(this.onlinePlayers[bdsuuid]).length != 0){
                listRes += `\n[${Object.values(this.onlines).find(client=>client.bds.uuid==bdsuuid)?.name}] \n${Object.values(this.onlinePlayers[bdsuuid]).map(playersInfo=>playersInfo.realName).join(', ')}`;
                plCount += Object.values(this.onlinePlayers[bdsuuid]).length;
            }
        }
        return listRes = `当前在线(${plCount}):` + listRes;
    }


    /**
     * @description: WS服务端玩家登记
     * @param {ClientManager} client
     * @param {object} playerInfo
     * @return {boolean}
     */    
    playerLogin(client, playerInfo){
        // 多设备登录失败
        for (let bdsUuid in this.onlinePlayers){
            if (this.onlinePlayers[bdsUuid][playerInfo.uuid] != undefined){
                return false;
            }
        }

        // 登记玩家
        if (this.onlinePlayers[client.bds.uuid] == undefined){
            this.onlinePlayers[client.bds.uuid] = {};
        }
        this.onlinePlayers[client.bds.uuid][playerInfo.uuid] = playerInfo;
        return true;
    }

    /**
     * @description: WS服务端玩家登出
     * @param {ClientManager} client
     * @param {object} playerInfo
     * @return {boolean}
     */    
    playerLogout(client, playerInfo){
        if (this.onlinePlayers[client.bds.uuid] == undefined){
            return true;
        }
        
        if (this.onlinePlayers[client.bds.uuid][playerInfo.uuid] != undefined){
            delete this.onlinePlayers[client.bds.uuid][playerInfo.uuid];
        }
        return true;
    }

    // 获取指定UID的客户端连接
    getClientById(id){
        for (let clientId in this.onlines){
            if (this.onlines[clientId].id == id){		
                return this.onlines[clientId];
            }
        }
        return null;
    }

    // 获取指定uuid的BDS客户端
    getClientByBDSuuid(uuid){
        if (uuid == null){return null;}
        for (let clientId in this.onlines){
            if (this.onlines[clientId]?.bds?.uuid == uuid){
                return this.onlines[clientId];
            }
        }
        return null;
    }

    // 获取主服
    getClientMainBDS(){
        for (let clientId in this.onlines){
            if (this.onlines[clientId]?.bds?.syncType == 'main'){
                return this.onlines[clientId];
            }
        }
        return null;
    }

    // 向在线的所有BDS更新云端在线BDS的信息
    // refOnlineBDSInfo(){
    //     let result = {
    //         serverConfig:{
    //             SyncInventoryDB: SyncInventoryDB,
    //             SyncMode: SyncMode
    //         }, 
    //         onlineBDSInfo:{}
    //     };
    //     this.forEach((client) =>{
    //         if (client.userType == "server"){
    //             result.onlineBDSInfo[client.BDSUid] = {
    //                 uid: client.id,
    //                 ServerName: client.name,
    //                 BDSType: client.BDSType,
    //                 BDSUid: client.BDSUid,
    //                 BDSIp: client.BDSIp,
    //                 BDSPort: client.BDSPort,
    //             };
    //         }
    //     });
    //     this.forEach((client) =>{
    //         if (client.userType == "server"){
    //             client.sendJson(result, "refOnlineBDSInfo");
    //         }
    //     });
    // }
}

class ClientManager extends Base_ClientManager {
    constructor(ws, timeout = 3000){
        super(ws);
        this.timeout = timeout;
        this.init = {};
        this.name = 'undefined';
        this.userType = 'undefined';     // 'bds' or 'player'
        // this.bds = {
        //     synctype: 'sub',      
        //     uuid: '',             
        //     ip: '',               
        //     port: 19132           
        // };
        // this.vanilla ??= {
        //     oriPos: {x:0,y:65,z:0,dimid:0},
        //     progress: 0,
        //     success: 0,
        //     failed: 0,
        //     tasking: false
        // };
        // this.pixelArt ??= {
        //     mapcolor: [],
        //     chunkStep: 64
        // };
    }

    // sendJson(json){
    //     return this.ws.send(JSON.stringify(json));
    // }

    /**
     * @description: 发送请求
     * @param {object} json
     * @param {function} callback
     * @param {number} timeout
     * @return {*}
     */
    sendJson(json, successCallback, errorCallback, timeout = this.timeout){
        if (json instanceof Response){json = json.json;}
        if (successCallback instanceof Function || errorCallback instanceof Function){
            if (!json.header){json.header = {};}
            const requestId = json.header.requestId || utils.uuidv4();
            json.header.requestId = requestId;
            // 设置超时拒绝
            const timeoutId = setTimeout(() => {
                if (WSS.pendingRequests.has(requestId)) {
                    const request = WSS.pendingRequests.get(requestId);
                    request.errorCallback(`请求超时: ${request.json?.header?.url??''} ${requestId}`);
                    WSS.pendingRequests.delete(requestId);
                    clearTimeout(request.timeout);
                }
            }, timeout);
            // 存储请求上下文
            WSS.pendingRequests.set(requestId, { 
                json: json,
                successCallback: successCallback instanceof Function ? successCallback : ()=>{}, 
                errorCallback: errorCallback instanceof Function ? errorCallback : (errmsg)=>{
                    WSS.logger.warn(errmsg);
                }, 
                timeout: timeoutId 
            });
            if (CONF.CONFIG.get('Websocket')['Debug'] == true){
                console.log('服务端发送: ', json, '\n-----------------------\n ');
            }
            return this.send(JSON.stringify(json));
        }
        if (!successCallback && !errorCallback){
            if (CONF.CONFIG.get('Websocket')['Debug'] == true){
                console.log('服务端发送: ', json, '\n-----------------------\n ');
            }
            return this.send(JSON.stringify(json));
        }
        throw new Error('function sendJson: successCallback and errorCallback must be function');
    }

    /**
     * @description: 异步发送请求(不会被其他事件监听到)
     * @param {object} json - 要发送的JSON数据
     * @param {number} [timeout=] - 超时时间(毫秒)
     * @return {Promise} - 返回包含响应结果的Promise
     */
    sendJsonAsync(json, timeout = this.timeout){
        return new Promise((resolve, reject) => {
            this.sendJson(json, 
            (request, response) => {
                resolve({req: request, res: response});
                return false;
            },
            (err)=>{
                WSC.logger.warn(err);
                resolve({req: null, res: null});
            },
            timeout);
        });
    }
    
    /**
     * @description: 发送文本消息
     * @param {string} msg
     * @return {*}
     */
    sendText(msg){
        return this.sendJson(new Response(Response.MODE.TEXT).setMsg(msg));
    }

    /**
     * @description: 发送控制台日志消息
     * @param {*} msg
     * @return {*}
     */    
    sendLogger(msg, level='info'){
        return this.sendJson(new Response().setUrl('/bds/loggerInfo').setData({
            msg: msg,
            level: level,
        }));
    }

    /**
     * @description: 让客户端执行命令
     * @param {string} cmd
     * @param {function} callback 
     * @return {*}
     */
    runcmd(cmd, callback) {
        return this.sendJson(new Response(Response.MODE.COMMAND_REQUEST).setCmd(cmd), callback);
    }


    /**
     * @description: 获取本客户端信息
     * @return {*}
     */    
    getClientInfo(){
        let info = {};
        for (let key in this){
            if (key == 'ws'){
                continue;
            }
            info[key] = JSON.parse(JSON.stringify(this[key]));
        }
        return info;
    }
}
module.exports = {
    ClientsManager,
    ClientManager
};